Pr. Solution Architect, Fuse Expert, Apache Committer Blog: http://cmoulliard.github.io Twitter: @cmoulliard Email: cmoulliard@redhat.com |
Committer on Apache Camel, Karaf, Fabric8, Hawtio … & PMC
Technology evangelist
Mountain Biker, Belgian Beer Fan, Blogger
Why integration is so hard & expensive ?
Integration Architecture
How can we simplify that ?
Ideal Integration Platform
Demo
|
|
|
|
|
2000 - EAI
2005 - ESB
2007 - EIP
Proprietary Standards based - JBI, SCA
From Standards Integration Framework
Architecture Centric (ESB) Distributed (Microservice - OSGI)
XML based
Inner conversion from Format-A to XML or XML to Format-B
ESB Centric Platform
|
Goal Integrate, Exchange, Communicate everywhere
Agile Project Mngt Scrum
Architecture Microservice
Automate Test, Build
Release more often
Standards & Technology used
Adopt it no more proprietary code
No viral license freedom to use, modify & redistribute it
|
See next conference about DevOps
Java Integration Framework (OSS)
Implements Domain Specific Language
Supports Enterprise Integration Patterns
Manage Complex use cases
correlation, aggregation
split, multicast
routing, filter
transformation
Fluent API
package my.cool.demo;
import org.apache.camel.builder.RouteBuilder;
public class ExampleRouteBuilder extends RouteBuilder {
@Override
public void configure() throws Exception {
from("amq:queue:quotes")
.filter().xpath("/quote/product/ = 'widget")
.bean("QuotesService", "widget")
.filter().xpath("/quote/product/ = 'gadget")
.bean("QuotesService","gadget");
}
}
Alternative : Spring, Blueprint
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
">
<bean id="quotesService" class="my.cool.demo.camel.QuotesService"/>"
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="amq:queue:quotes"/>
<filter>
<xpath>"/quote/product/ = 'widget"</xpath>
</filter>
<bean id="quotesService" method="widget"/>
<filter>
<xpath>"/quote/product/ = 'gadget"</xpath>
</filter>
<bean id="quotesService" method="gadget"/>
</route>
</camelContext>
</beans>Use Same Language, grammar between actors:
developer, analyst & architect
Adopt Domain Specific Language
Reduce Functional to Develop Time
Workflow Camel project Collection of routes
Route Sum of Processor(s) + Interceptor(s)
Route Produce or Consume Messages
To trace, log, capture business events
Data Transformation for complex use case
package my.cool.demo;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.camel.Exchange;
public interface DataFormat {
void marshal(Exchange exchange, Object graph, OutputStream stream) throws Exception;
Object unmarshal(Exchange exchange, InputStream stream) throws Exception;
}Marshalling : Object XML (JAXB)
Unmarshalling : XML Object (JAXB)
|
In-Memory bus
Support Object : XML, File, Stream, Bytes
Predicate & Expression language (xslt, xpath, …)
Sync/Async exchanges
Threads Management
Tx Architecture
public class FilterTest extends CamelTestSupport {
@EndpointInject(uri = "mock:result")
protected MockEndpoint resultEndpoint;
@Produce(uri = "direct:start")
protected ProducerTemplate template;
@Test
public void testSendMatchingMessage() throws Exception {
String expectedBody = "<matched/>";
resultEndpoint.expectedBodiesReceived(expectedBody);
template.sendBodyAndHeader(expectedBody, "foo", "bar");
resultEndpoint.assertIsSatisfied();
}
@Override
protected RouteBuilder createRouteBuilder() {
return new RouteBuilder() {
public void configure() {
from("direct:start").filter(header("foo").isEqualTo("bar")).to("mock:result");
}
};
}Benefit from your Java JUnit Testing Knowledge
// we do special error handling for when OrderFailedException is thrown
onException(OrderFailedException.class)
// we mark the exchange as handled so the caller doesn't receive the
// OrderFailedException but whatever we want to return instead
.handled(true)
// this bean handles the error handling where we can customize the error response
.bean(OrderService.class, "orderFailed")
// and since this is an unit test we use mocks for testing
.to("mock:error");// this is just the generic error handler where we set the destination
// and the number of redeliveries we want to try
errorHandler(deadLetterChannel("mock:error").maximumRedeliveries(1));from("direct:start")
// this bean is our order service
.bean(OrderService.class, "handleOrder")
// this is the destination if the order is OK
.to("mock:result");Capitalize your Java skills about Exception Management
<route>
<from uri="direct:start"/>
<doTry>
<process ref="processorFail"/>
<to uri="mock:result"/>
<doCatch>
<exception>java.io.IOException</exception>
<exception>java.lang.IllegalStateException</exception>
<to uri="mock:catch"/>
</doCatch>
<doFinally>
<to uri="mock:finally"/>
</doFinally>
</doTry>
</route>Mimic Java Try/Catch/Block Structure
Camel routes isolated from each other (classloader)
Bundle CamelContext boundary acting as a Local BUS
Camel routes can have different SLA (Threads, Policies, …)
Camel routes can be started/stopped/updated
Simplify maintenance process
Opensource integration project - http://fabric8.io
Mission simplify management & deployment java integration services on different machines & JVMs
Manage container creation (locally, remotely, cloud, openshift, docker, …)
Visualise what is running into JVM to understand your platform
Monitor whats running and easily scaling up or down
Support Upgrade via Version changes and Rollback
Virtualize services (endpoints), processes
Search and storage engine for logs, camel, messages, metrics
Services & governance : Apiman
SSO, Oauth2 : Keycloak
Policy based
More info - see Fuse In Action Lab